package com.smart.wap.service;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.smart.common.entities.domain.LoginResult;
import com.smart.common.entities.enums.SmsScene;
import com.smart.manager.member.entities.models.MemberProfileMain;
import com.smart.manager.member.entities.models.query.QMemberProfileMain;
import com.smart.manager.work.entities.enums.StaffStatus;
import com.smart.manager.work.entities.models.BasicStaff;
import com.smart.manager.work.entities.models.query.QBasicStaff;
import com.smart.service.sms.SmsService;
import com.smart.utils.MemberAcl;
import com.smart.utils.WorkAcl;
import com.smart.wap.bodys.WorkLoginBody;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Optional;

/**
 * @author Admin
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class WorkLoginService {

    private final SmsService smsService;
    private final AppLoginService appLoginService;

    /**
     * 喂养端登录
     *
     * @param body 登录
     * @return {@link String}
     */
    public LoginResult login(WorkLoginBody.LoginBody body) {
        log.warn("喂养端登录");
        Optional<BasicStaff> orEmpty = new QBasicStaff().phone.eq(body.getPhone()).findOneOrEmpty();
        Assert.isFalse(orEmpty.isEmpty(), "没有该手机号! 请联系管理员开通!");
        BasicStaff staff = orEmpty.get();
        boolean check = DigestUtil.bcryptCheck(body.getPassword(), staff.getPassword());
        Assert.isTrue(check, "密码不正确!");
        Assert.isTrue(staff.getStatus().equals(StaffStatus.NORMAL), "账号异常禁止登录!");
        String accessToken = WorkAcl.login(staff.getId());
        String refreshToken = DigestUtil.md5Hex(accessToken).toUpperCase();
        LocalDateTime refreshExpiredTime = LocalDateTime.now().plusMonths(6L);
        LoginResult loginResult = new LoginResult().setSuccess(true).setTips("登录成功！").setAccessToken(accessToken).setRefreshToken(refreshToken);
        staff.setRefreshToken(refreshToken).setRefreshExpiredTime(refreshExpiredTime).update();
        return loginResult;
    }

    /**
     * 获取验证码
     *
     * @param body 手机号
     */
    public void getAuthCode(WorkLoginBody.authCodeBody body) {
        Optional<BasicStaff> staff = new QBasicStaff().phone.eq(body.getPhone()).setMaxRows(1).findOneOrEmpty();
        Assert.isFalse(staff.isEmpty(), "没有该账号请联系管理员开通!");
        Assert.isTrue(staff.get().getStatus().equals(StaffStatus.NORMAL), "该账号异常! 请联系管理员!");
        smsService.sendCaptchaCode(SmsScene.WORKER_LOGIN, body.getPhone());
    }

    /**
     * 验证码登录
     *
     * @param body 手机号 ,验证码
     */
    public LoginResult authCodeLogin(WorkLoginBody.authCodeLoginBody body) {
        Optional<BasicStaff> staff = new QBasicStaff().phone.eq(body.getPhone()).setMaxRows(1).findOneOrEmpty();
        Assert.isFalse(staff.isEmpty(), "没有该账号请联系管理员开通!");
        Assert.isTrue(staff.get().getStatus().equals(StaffStatus.NORMAL), "该账号异常! 请联系管理员!");
        smsService.checkCaptchaCode(SmsScene.WORKER_LOGIN, body.getPhone(), body.getAuthCode());
        String accessToken = WorkAcl.login(staff.get().getId());
        String refreshToken = DigestUtil.md5Hex(accessToken).toUpperCase();
        LocalDateTime refreshExpiredTime = LocalDateTime.now().plusMonths(6L);
        staff.get().setOpenId(body.getOpenId());
        LoginResult loginResult = new LoginResult().setSuccess(true).setTips("登录成功！").setAccessToken(accessToken).setRefreshToken(refreshToken);
        staff.get().setRefreshToken(refreshToken).setRefreshExpiredTime(refreshExpiredTime).update();
        return loginResult;
    }

    /**
     * 根据微信授权码登录
     * @return {@code LoginResult}
     */
    public LoginResult actionWxUser(String openid) {
        BasicStaff profileMain = new QBasicStaff().openId.eq(openid).setMaxRows(1).findOne();
        if (ObjUtil.isNotNull(profileMain)) {
            return loginSuccessHandler(profileMain,true);
        }
        return new LoginResult().setSuccess(false).setTips("登录失败,请继续使用手机短信验证码登录").setOpenId(openid);
    }


    /**
     * 登录成功处理程序 并设置刷新令牌和最后登录时间
     *
     * @param isUpdate    是否是更新模式
     * @return {@code LoginResult}
     */
    private LoginResult loginSuccessHandler(BasicStaff staff, boolean isUpdate) {
        String accessToken = WorkAcl.login(staff.getId());
        String refreshToken = DigestUtil.md5Hex(accessToken).toUpperCase();
        //记录会员登录时间 并设置会员刷新令牌有效期和值 刷新令牌有效期为6个月
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime refreshExpiredTime = now.plusMonths(6L);
        LoginResult loginResult = new LoginResult().setSuccess(true).setTips("登录成功！").setAccessToken(accessToken).setRefreshToken(refreshToken);
        staff.setRefreshToken(refreshToken).setRefreshExpiredTime(refreshExpiredTime);
        //修改描述下 刷新数据
        if (isUpdate) {
            staff.update();
            return loginResult;
        }
        return loginResult;
    }



    /**
     * 自动刷新身份令牌
     * @param body
     * @return {@code LoginResult}
     */
    public LoginResult refreshToken(WorkLoginBody.RefreshTokenBody body) {
        BasicStaff basicStaff = new QBasicStaff().refreshToken.eq(body.getRefreshToken())
                .refreshExpiredTime.isNotNull()
                .refreshExpiredTime.after(LocalDateTime.now())
                .setMaxRows(1).findOne();
        Assert.notNull(basicStaff, "无效的刷新令牌");
        String accessToken = WorkAcl.login(basicStaff.getId());
        return new LoginResult().setAccessToken(accessToken).setSuccess(true)
                .setRefreshToken(basicStaff.getRefreshToken())
                .setTips("身份令牌刷新成功");
    }
}
